#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stddef.h>
#include <time.h>
#include <sys/stat.h>

#include "interaction.h"
#include "user_device.h"
#include "ticket_device.h"
#include "app.h"
#include "log.h"
#include "list.h"
#include "communication.h"

static void itoa(int i, char* string);

/**
 * @brief   用户登录
 * @param   interaction:包含底层数据结构的用来交互的结构体
 * @return  根据用户不同的选择返回不同的宏
 */
int user_login(struct data_packet data, int clientfd, struct interaction *interaction)
{
    char user_id_or_phone_num[PHONE_NUM_SIZE], passwd[USER_PASSWD_SIZE];
    char ack_data;
    int ret = NO_ERROR;

    if (!interaction && !clientfd) {
        DEBUG("PARAM ERROR\n");
        return false;
    }

    memcpy(user_id_or_phone_num, data.data[0], strlen(data.data[0]));
    memcpy(passwd, data.data[1], strlen(data.data[1]));

    user_id_or_phone_num[strlen(data.data[0])] = '\0';
    passwd[strlen(data.data[1])] = '\0';

    /*匹配数据库中的信息*/
    ret = match_user_info(user_id_or_phone_num, passwd,
                            &interaction->user_head);

    if (ret == ID_NO_MATCH) {
        ack_data = LOGIN_NO_MATCH_ERR_ACK;
    } else {
        ack_data = LOGIN_SUCCESS_ACK;
    }

    send_ack(clientfd, ack_data);
    return true;
}

/**
 * @brief   用户注册
 * @param   interaction:包含底层数据结构的用来交互的结构体
 * @return  根据用户不同的选择返回不同的宏
 */
int user_register(struct data_packet data, int clientfd, struct interaction *interaction)
{
    char user_id[USER_ID_SIZE];
    char passwd[USER_PASSWD_SIZE];
    char name[NAME_SIZE];
    char citizen_id[CITIZEN_ID_SIZE];
    char phone_num[PHONE_NUM_SIZE];
    int ret = NO_ERROR;
    char ack_data;

    struct user *need_add = NULL;

    if (!interaction && !clientfd) {
        DEBUG("PARAM ERROR\n");
        return false;
    }

    memcpy(user_id, data.data[0], strlen(data.data[0]));
    memcpy(passwd, data.data[1], strlen(data.data[1]));
    memcpy(name, data.data[2], strlen(data.data[2]));
    memcpy(citizen_id, data.data[3], strlen(data.data[3]));
    memcpy(phone_num, data.data[4], strlen(data.data[4]));

    user_id[strlen(data.data[0])] = '\0';
    passwd[strlen(data.data[1])] = '\0';
    name[strlen(data.data[2])] = '\0';
    citizen_id[strlen(data.data[3])] = '\0';
    phone_num[strlen(data.data[4])] = '\0';

    /*匹配数据库中的信息*/
    /* 判断刚注册的用户名和身份证号是否与他人重复 */
    ret = is_user_info_repeat(user_id, citizen_id,
                            phone_num,
                            &interaction->user_head);

    if (ret != USER_REPEAT) {
        need_add = (struct user *)malloc(sizeof(struct user));

        strncpy(need_add->passwd, passwd, sizeof(passwd));
        strncpy(need_add->user_id, user_id, sizeof(user_id));
        strncpy(need_add->name, name, sizeof(name));
        strncpy(need_add->citizen_id, citizen_id,
                                            sizeof(citizen_id));
        strncpy(need_add->phone_num, phone_num,
                                            sizeof(phone_num));

        list_add_tail(&need_add->list, &interaction->user_head);

        ack_data = REGISTER_SUCCESS_ACK;
    } else {
        ack_data = REGISTER_USER_REPEAT_ERR_ACK;
    }

    send_ack(clientfd, ack_data);
    return true;
}

int get_ticket_from_py(struct data_packet data, int clientfd, char *ticket_buffer)
{
    char from_station[ORIGIN_PLACE_SIZE] = {0};
    char to_station[DESTINATION_SIZE] = {0};
    char to_date[TO_DATE_SIZE] = {0};
    unsigned int file_length_bytes;
    FILE *respond_file;
    int request_file;

    strncpy(from_station, data.data[0], strlen(data.data[0]));
    strncpy(to_station, data.data[1], strlen(data.data[1]));
    strncpy(to_date, data.data[2], strlen(data.data[2]));

    from_station[strlen(data.data[0])] = '\0';
    to_station[strlen(data.data[1])] = '\0';
    to_date[strlen(data.data[2])] = '\0';

    /* 将用户想搜索的车站和日期写入文件中，让py那边去读取 */
    request_file = open("/home/ubuntu/request_file.txt", 
        O_RDWR | O_CREAT);
    if (-1 == request_file) {
        request_file = open("/home/ubuntu/request_file.txt", 
            O_RDWR | O_CREAT);
        if (-1 == request_file) {
            DEBUG("FAIL TO OPEN REQUEST FILE\n");
            return false;
        }
    }

    write(request_file, from_station, strlen(from_station));
    write(request_file, ",", 1);
    write(request_file, to_station, strlen(to_station));
    write(request_file, ",", 1);
    write(request_file, to_date, strlen(to_date));
    write(request_file, ",", 1);

    close(request_file);

    /* while是为了等待py那边响应，如果没有响应，即读取不到py那边写下的文件，就会一直循环 */
    while (1) {
        if (0 == access("/home/ubuntu/train_massage.txt", 0)) {
            respond_file = fopen("/home/ubuntu/train_massage.txt", "r");
            if (!respond_file) {
                respond_file = fopen("/home/ubuntu/train_massage.txt", "r");
                if (!respond_file) {
                    DEBUG("FAIL TO OPEN USER DATA FILE\n");
                    return false;
                }
            }
            sleep(3);

			fseek(respond_file, 0, SEEK_END);
            file_length_bytes = ftell(respond_file);
            fseek(respond_file, 0, SEEK_SET);
            
            fread(ticket_buffer, file_length_bytes, 1, respond_file);
            ticket_buffer[file_length_bytes] = '\0';
            break;
        } else {
            continue;
        }
    }

    fclose(respond_file);
    return true;
}

void send_ticket_to_app(char *ticket_buffer, int clientfd)
{
    struct communication_core communication;
    int ret;
    //发送超时设置为10秒
    struct timeval timeout = {10,0};
    union val {
        int				i_val;
        long				l_val;
        struct linger		linger_val;
        struct timeval	timeval_val;
    } val;
    unsigned int len;

    /*通信协议初始化*/
    communication_core_init(&communication);

    communication.data.sendfd = clientfd;
    communication.data.send_data_packet.cmd_type = TICKET_CMD_TYPE;
    communication.data.send_data_packet.cmd = FIND_TICKET_CMD;
    communication.data.send_data_packet.data[0] = ticket_buffer;
    
    /*设置超时时间*/
    len = sizeof(val);
    getsockopt(clientfd, SOL_SOCKET, SO_SNDTIMEO, &val, &len);
    len = sizeof(struct timeval);
    setsockopt(clientfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, len);

    /* 发送数据 */
    communication.dev.cmd = COMM_SEND;
    ret = communication.ioctl(&communication.dev, communication.dev.cmd, communication.dev.arg);
    reset_data_packet(&communication.data.send_data_packet);

    if (ret != TRUE) {
        DEBUG("SEND DATA FAIL !\r\n");
    }

    len = sizeof(val);
    setsockopt(clientfd, SOL_SOCKET, SO_SNDTIMEO, &val, len);
    /* 发送完成后将车票数据的文件删除 */
    remove("/home/ubuntu/train_massage.txt");
}

/**
 * @brief   用户买票
 * @param   interaction:包含底层数据结构的用来交互的结构体
 * @return  根据用户不同的选择返回不同的宏
 */
int buy_ticket(struct data_packet data, int clientfd, struct list_head *ticket_head, struct list_head *user_ticket_head, struct list_head *user_head)
{
    char ack_data;
    struct list_head *pos, *pos2, *pos3;
    struct user *scan_list;
    struct ticket *scan_list_2;
    struct user_ticket *scan_list_3;
    char type_num[2];
    int ticket_num;

    struct user_ticket *need_add = (struct user_ticket *)malloc(sizeof(struct user_ticket));

    /* 将数据包中的数据放入结构体中 */
    strncpy(need_add->id, data.data[0], strlen(data.data[0]));
    strncpy(need_add->origin_place, data.data[1], strlen(data.data[1]));
    strncpy(need_add->destination, data.data[2], strlen(data.data[2]));
    strncpy(need_add->departure_time, data.data[3],
                                        strlen(data.data[3]));
    strncpy(need_add->arrival_time, data.data[4],
                                        strlen(data.data[4]));
    strncpy(need_add->train_number, data.data[5],
                                        strlen(data.data[5]));
    strncpy(need_add->price, data.data[6], strlen(data.data[6]));
    strncpy(need_add->date, data.data[7], strlen(data.data[7]));
    strncpy(need_add->ticket_type, data.data[8], strlen(data.data[8]));
    strncpy(type_num, data.data[9], strlen(data.data[9]));

    /* strncpy之后要补结束符 */
    need_add->id[strlen(data.data[0])] = '\0';
    need_add->origin_place[strlen(data.data[1])] = '\0';
    need_add->destination[strlen(data.data[2])] = '\0';
    need_add->departure_time[strlen(data.data[3])] = '\0';
    need_add->arrival_time[strlen(data.data[4])] = '\0';
    need_add->train_number[strlen(data.data[5])] = '\0';
    need_add->price[strlen(data.data[6])] = '\0';
    need_add->date[strlen(data.data[7])] = '\0';
    need_add->ticket_type[strlen(data.data[8])] = '\0';
    type_num[strlen(data.data[9])] = '\0';

    /* 比较用户id */
    list_for_each (pos, user_head) {
        scan_list = list_entry(pos, struct user, list);
        if (0 == strcmp(scan_list->user_id, data.data[0])) {
            strncpy(need_add->name, scan_list->name, strlen(scan_list->name));
            strncpy(need_add->citizen_id, scan_list->citizen_id, strlen(scan_list->citizen_id));
            strncpy(need_add->phone_num, scan_list->phone_num, strlen(scan_list->phone_num));
        }
    }

    /*判断是否重复购买*/
    list_for_each (pos3, user_ticket_head) {
        scan_list_3 = list_entry(pos3, struct user_ticket, list);
        if (0 == strcmp(scan_list_3->id, need_add->id) && 
            0 == strcmp(scan_list_3->date, need_add->date) &&
            0 == strcmp(scan_list_3->train_number, need_add->train_number)) {
            
            ack_data = REPEAT_ACK;
            send_ack(clientfd, ack_data);
            free(need_add);
            return false;
        }
    }

    /* 比较车次和日期 */
    list_for_each (pos2, ticket_head) {
        scan_list_2 = list_entry(pos2, struct ticket, list);
        if (0 == strcmp(scan_list_2->train_number, data.data[5])) {
            if (0 == strcmp(scan_list_2->date, data.data[7])) {
                switch (type_num[0]) {
                    /* 判断座位是否有票 */
                    case '1' :
                        if (atoi(scan_list_2->ticket_type1_num) == 0) {
                            ack_data = NO_TICKET_NUM_ACK;
                            send_ack(clientfd, ack_data);
                            free(need_add);
                            return false;
                        }
                        ticket_num = atoi(scan_list_2->ticket_type1_num) - 1;
                        itoa(ticket_num, scan_list_2->ticket_type1_num);
                        break;
                    case '2' :
                        if (atoi(scan_list_2->ticket_type2_num) == 0) {
                            ack_data = NO_TICKET_NUM_ACK;
                            send_ack(clientfd, ack_data);
                            free(need_add);
                            return false;
                        }
                        ticket_num = atoi(scan_list_2->ticket_type2_num) - 1;
                        itoa(ticket_num, scan_list_2->ticket_type2_num);
                        break;
                    case '3' :
                        if (atoi(scan_list_2->ticket_type3_num) == 0) {
                            ack_data = NO_TICKET_NUM_ACK;
                            send_ack(clientfd, ack_data);
                            free(need_add);
                            return false;
                        }
                        ticket_num = atoi(scan_list_2->ticket_type3_num) - 1;
                        itoa(ticket_num, scan_list_2->ticket_type3_num);
                        break;
                    case '4' :
                        if (atoi(scan_list_2->ticket_type4_num) == 0) {
                            ack_data = NO_TICKET_NUM_ACK;
                            send_ack(clientfd, ack_data);
                            free(need_add);
                            return false;
                        }
                        ticket_num = atoi(scan_list_2->ticket_type4_num) - 1;
                        itoa(ticket_num, scan_list_2->ticket_type4_num);
                        break;
                }
            }
        }
    }

    /* 将购买的用户车票信息加入链表中 */
    list_add_tail(&need_add->list, user_ticket_head);

    /* 发送成功消息到安卓端 */
    ack_data = BUY_TICEKT_SUCCESS_ACK;
    send_ack(clientfd, ack_data);

    return true;
}

/**
 * @brief:查找自己购买的车票信息
 * @return:有车票返回true，没有车票返回false
 */
int find_order(struct data_packet data, int clientfd, struct list_head *user_ticket_head, struct list_head *temporary_head)
{
    char id[USER_ID_SIZE] = {0};
    struct list_head *pos;
    struct user_ticket *scan_list;
    struct user_ticket *target_ticket;
    int ret = false;

    memcpy(id, data.data[0], strlen(data.data[0]));
    /*将请求的id的车票在user_ticket中搜索出来*/
    list_for_each (pos, user_ticket_head) {
        scan_list = list_entry(pos, struct user_ticket, list);
        if (0 == strcmp(scan_list->id, id)) {
            target_ticket = (struct user_ticket *)malloc(sizeof(struct user_ticket));

            /* 将查询到的车票放入申请的结构体中 */
            strncpy(target_ticket->origin_place, scan_list->origin_place, 
                                                sizeof(scan_list->origin_place));
            strncpy(target_ticket->destination, scan_list->destination, 
                                                sizeof(scan_list->destination));
            strncpy(target_ticket->departure_time, scan_list->departure_time,
                                                sizeof(scan_list->departure_time));
            strncpy(target_ticket->arrival_time, scan_list->arrival_time,
                                                sizeof(scan_list->arrival_time));
            strncpy(target_ticket->train_number, scan_list->train_number,
                                                sizeof(scan_list->train_number));
            strncpy(target_ticket->price, scan_list->price, 
                                                sizeof(scan_list->price));
            strncpy(target_ticket->date, scan_list->date, 
                                                sizeof(scan_list->date));
            strncpy(target_ticket->citizen_id, scan_list->citizen_id, 
                                                sizeof(scan_list->citizen_id));
            strncpy(target_ticket->name, scan_list->name, 
                                                sizeof(scan_list->name));    
            strncpy(target_ticket->phone_num, scan_list->phone_num, 
                                                sizeof(scan_list->phone_num));                                                                                        
            strncpy(target_ticket->ticket_type, scan_list->ticket_type, 
                                                sizeof(scan_list->ticket_type));
            /* 将查询到的车票加入链表中 */
            list_add_tail(&target_ticket->list, temporary_head);
            ret = true;
        }
    }

    return ret;
}

/**
 * @brief:退票
 * @return:退票成功返回true，退票失败返回false
 */
int return_ticket(struct data_packet data, int clientfd, struct list_head *user_ticket_head, struct list_head *ticket_head)
{
    char id[USER_ID_SIZE] = {0};
    char train_num[TRAIN_NUM_SIZE] = {0};
    struct list_head *pos, *n, *pos2;
    struct user_ticket *scan_list;
    struct ticket *scan_ticket_list;
    char ticket_type[TICKET_TYPE_SIZE] = {0};
    int ret = FALSE_;
    int ticket_num;

    memcpy(id, data.data[0], strlen(data.data[0]));
    memcpy(train_num, data.data[1], strlen(data.data[1]));
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    id[strlen(data.data[0])] = '\0';
    train_num[strlen(data.data[1])] = '\0';

    /* 匹配ID和车次 */
    list_for_each_safe (pos, n, user_ticket_head) {
        scan_list = list_entry(pos, struct user_ticket, list);
        if (0 == strcmp(scan_list->id, id) && 
            0 == strcmp(scan_list->train_number, train_num)) {
            ret = TRUE;
            strncpy(ticket_type, scan_list->ticket_type, strlen(scan_list->ticket_type));
            ticket_type[strlen(scan_list->ticket_type)] = '\0';
            list_del(pos);
            free(scan_list);
        }
    }

    /* 将车票加回车票库中 */
    list_for_each (pos2, ticket_head) {
        scan_ticket_list = list_entry(pos2, struct ticket, list);
        if (0 == strcmp(scan_ticket_list->train_number, train_num)) {
            if (0 == strcmp(ticket_type, "二等座") ||
                0 == strcmp(ticket_type, "无座")) {
                ticket_num = atoi(scan_ticket_list->ticket_type1_num);
                ticket_num++;
                itoa(ticket_num, scan_ticket_list->ticket_type1_num);
            } else if (0 == strcmp(ticket_type, "一等座") ||
                        0 == strcmp(ticket_type, "硬座")) {
                ticket_num = atoi(scan_ticket_list->ticket_type2_num);
                ticket_num++;
                itoa(ticket_num, scan_ticket_list->ticket_type2_num);
            } else if (0 == strcmp(ticket_type, "特等座") ||
                        0 == strcmp(ticket_type, "硬卧")) {
                ticket_num = atoi(scan_ticket_list->ticket_type3_num);
                ticket_num++;
                itoa(ticket_num, scan_ticket_list->ticket_type3_num);
            } else if (0 == strcmp(ticket_type, "软卧")) {
                ticket_num = atoi(scan_ticket_list->ticket_type4_num);
                ticket_num++;
                itoa(ticket_num, scan_ticket_list->ticket_type4_num);
            }
        }
    }

    return ret;
}

/**
 * @brief:添加车票
 */
void add_ticket(struct data_packet data, int clientfd, struct list_head *ticket_head)
{
    char train_number[TRAIN_NUM_SIZE] = {0};
    char date[TO_DATE_SIZE] = {0};
    struct ticket *need_add;
    struct list_head *pos;
    struct ticket *scan_list;
    char ack_data;
    int is_repeat = false;

    strncpy(train_number, data.data[0], strlen(data.data[0]));
    strncpy(date, data.data[5], strlen(data.data[5]));

    /* 判断是否与库中的车票重复 */
    list_for_each (pos, ticket_head) {
        scan_list = list_entry(pos, struct ticket, list);
        if (0 == strcmp(scan_list->train_number, train_number) && 
            0 == strcmp(scan_list->date, date)) {
            is_repeat = true;
        }
    }

    /* 不重复就将车票信息加入 */
    if (is_repeat == false) {
        need_add = (struct ticket *)malloc(sizeof(struct ticket));
        strncpy(need_add->train_number, data.data[0], strlen(data.data[0]));
        strncpy(need_add->origin_place, data.data[1], strlen(data.data[1]));
        strncpy(need_add->destination, data.data[2], strlen(data.data[2]));
        strncpy(need_add->departure_time, data.data[3], strlen(data.data[3]));
        strncpy(need_add->arrival_time, data.data[4], strlen(data.data[4]));
        strncpy(need_add->date, data.data[5], strlen(data.data[5]));
        strncpy(need_add->ticket_type1_num, data.data[6], strlen(data.data[6]));
        strncpy(need_add->ticket_type2_num, data.data[7], strlen(data.data[7]));
        strncpy(need_add->ticket_type3_num, data.data[8], strlen(data.data[8]));
        strncpy(need_add->ticket_type4_num, data.data[9], strlen(data.data[9]));
        strncpy(need_add->type1_price, data.data[10], strlen(data.data[10]));
        strncpy(need_add->type2_price, data.data[11], strlen(data.data[11]));
        strncpy(need_add->type3_price, data.data[12], strlen(data.data[12]));
        strncpy(need_add->type4_price, data.data[13], strlen(data.data[13]));
        need_add->train_number[strlen(data.data[0])] = '\0';
        need_add->origin_place[strlen(data.data[1])] = '\0';
        need_add->destination[strlen(data.data[2])] = '\0';
        need_add->departure_time[strlen(data.data[3])] = '\0';
        need_add->arrival_time[strlen(data.data[4])] = '\0';
        need_add->date[strlen(data.data[5])] = '\0';
        need_add->ticket_type1_num[strlen(data.data[6])] = '\0';
        need_add->ticket_type2_num[strlen(data.data[7])] = '\0';
        need_add->ticket_type3_num[strlen(data.data[8])] = '\0';
        need_add->ticket_type4_num[strlen(data.data[9])] = '\0';
        need_add->type1_price[strlen(data.data[10])] = '\0';
        need_add->type2_price[strlen(data.data[11])] = '\0';
        need_add->type3_price[strlen(data.data[12])] = '\0';
        need_add->type4_price[strlen(data.data[13])] = '\0';

        list_add_tail(&need_add->list, ticket_head);

        ack_data = ADD_TICKET_SUCCESS_ACK;
        send_ack(clientfd, ack_data);
    } else {
        ack_data = ADD_TICKET_FALSE_ACK;
        send_ack(clientfd, ack_data);
    }
}

/**
 * @brief:添加用户
 */
void add_user(struct data_packet data, int clientfd, struct list_head *user_head)
{
    char user_id[USER_ID_SIZE] = {0};
    char passwd[USER_PASSWD_SIZE] = {0};
    char name[NAME_SIZE] = {0};
    char citizen_id[CITIZEN_ID_SIZE] = {0};
    char phone_num[PHONE_NUM_SIZE] = {0};

    struct user *need_add;
    struct list_head *pos;
    struct user *scan_list;
    char ack_data;
    int is_repeat = FALSE_;

    strncpy(user_id, data.data[0], strlen(data.data[0]));
    strncpy(passwd, data.data[1], strlen(data.data[1]));
    strncpy(name, data.data[2], strlen(data.data[2]));
    strncpy(citizen_id, data.data[3], strlen(data.data[3]));
    strncpy(phone_num, data.data[4], strlen(data.data[4]));

    /* 判断是否重复 */
    list_for_each (pos, user_head) {
        scan_list = list_entry(pos, struct user, list);
        if (0 == strcmp(scan_list->user_id, user_id)) {
            is_repeat = true;
        }
        if (0 == strcmp(scan_list->name, name)) {
            is_repeat = true;
        }
        if (0 == strcmp(scan_list->citizen_id, citizen_id)) {
            is_repeat = true;
        }
        if (0 == strcmp(scan_list->phone_num, phone_num)) {
            is_repeat = true;
        }
    }

    /* 不重复就将用户信息加入 */
    if (is_repeat == FALSE_) {
        need_add = (struct user *)malloc(sizeof(struct user));
        strncpy(need_add->user_id, user_id, strlen(user_id));
        strncpy(need_add->passwd, passwd, strlen(passwd));
        strncpy(need_add->name, name, strlen(name));
        strncpy(need_add->citizen_id, citizen_id, strlen(citizen_id));
        strncpy(need_add->phone_num, phone_num, strlen(phone_num));
        need_add->user_id[strlen(user_id)] = '\0';
        need_add->passwd[strlen(passwd)] = '\0';
        need_add->name[strlen(name)] = '\0';
        need_add->citizen_id[strlen(citizen_id)] = '\0';
        need_add->phone_num[strlen(phone_num)] = '\0';
        
        list_add_tail(&need_add->list, user_head);
        ack_data = ADD_USER_SUCCESS_ACK;
        send_ack(clientfd, ack_data);
    } else {
        ack_data = ADD_USER_FALSE_ACK;
        send_ack(clientfd, ack_data);
    }
}

/**
 * @brief:删除车票
 */
void delete_ticket(struct data_packet data, int clientfd, struct list_head *ticket_head, struct list_head *user_ticket_head)
{
    char train_number[TRAIN_NUM_SIZE];
    struct list_head *pos, *n, *pos2, *n2;
    struct ticket *scan_list;
    struct user_ticket *scan_list2;
    int is_delete2 = FALSE_;
    char ack_data;

    /* 将用户已买的车票删除 */
    strncpy(train_number, data.data[0], strlen(data.data[0]));
    list_for_each_safe (pos, n, user_ticket_head) {
        scan_list2 = list_entry(pos, struct user_ticket, list);
        if (0 == strcmp(scan_list2->train_number, train_number)) {
            list_del(pos);
        }
    }

    /* 将车票库中的车票删除 */
    list_for_each_safe (pos2, n2, ticket_head) {
        scan_list = list_entry(pos2, struct ticket, list);
        if (0 == strcmp(scan_list->train_number, train_number)) {
            is_delete2 = TRUE;
            list_del(pos2);
        }
    }

    if (is_delete2 == true) {
        ack_data = ADMIN_DELETE_TICKET_SUCCESS_ACK;
    } else {
        ack_data = ADMIN_DELETE_TICKET_FALSE_ACK;
    }
    send_ack(clientfd, ack_data);
}

/**
 * @brief:删除用户
 */
void delete_user(struct data_packet data, int clientfd, struct list_head *user_head)
{
    char user_id[USER_ID_SIZE];
    struct list_head *pos, *n;
    struct user *scan_list;
    int is_delete = FALSE_;
    char ack_data;

    strncpy(user_id, data.data[0], strlen(data.data[0]));
    user_id[strlen(data.data[0])] = '\0';

    /* 匹配用户信息后删除 */
    list_for_each_safe (pos, n, user_head) {
        scan_list = list_entry(pos, struct user, list);
        if (0 == strcmp(scan_list->user_id, user_id)) {
            is_delete = TRUE;
            list_del(pos);
        }
    }

    if (is_delete == true) {
        ack_data = ADMIN_DELETE_USER_SUCCESS_ACK;
    } else {
        ack_data = ADMIN_DELETE_USER_FALSE_ACK;
    }
    send_ack(clientfd, ack_data);
}

/**
 * @brief:修改车票信息
 */
void change_ticket(struct data_packet data, int clientfd, struct list_head *ticket_head, struct list_head *user_ticket_head)
{
    char ack_data;
    char old_train_number[TRAIN_NUM_SIZE];
    struct ticket *scan_list;
    int i;
    struct list_head *pos, *pos2;

    strncpy(old_train_number, data.data[0], strlen(data.data[0]));
    list_for_each (pos, ticket_head) {
        scan_list = list_entry(pos, struct ticket, list);
        if (0 == strcmp(scan_list->train_number, old_train_number)) {
            /* 清空数据 */
            for (i = 0; i < sizeof(scan_list->train_number); i++) {
                scan_list->train_number[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->origin_place); i++) {
                scan_list->origin_place[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->destination); i++) {
                scan_list->destination[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->departure_time); i++) {
                scan_list->departure_time[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->arrival_time); i++) {
                scan_list->arrival_time[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->date); i++) {
                scan_list->date[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->ticket_type1_num); i++) {
                scan_list->ticket_type1_num[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->ticket_type2_num); i++) {
                scan_list->ticket_type2_num[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->ticket_type3_num); i++) {
                scan_list->ticket_type3_num[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->ticket_type4_num); i++) {
                scan_list->ticket_type4_num[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->type1_price); i++) {
                scan_list->type1_price[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->type2_price); i++) {
                scan_list->type2_price[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->type3_price); i++) {
                scan_list->type3_price[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->type4_price); i++) {
                scan_list->type4_price[i] = 0;
            }
            /* 导入数据 */
            strncpy(scan_list->train_number, data.data[1], strlen(data.data[1]));
            strncpy(scan_list->origin_place, data.data[2], strlen(data.data[2]));
            strncpy(scan_list->destination, data.data[3], strlen(data.data[3]));
            strncpy(scan_list->departure_time, data.data[4], strlen(data.data[4]));
            strncpy(scan_list->arrival_time, data.data[5], strlen(data.data[5]));
            strncpy(scan_list->date, data.data[6], strlen(data.data[6]));
            strncpy(scan_list->ticket_type1_num, data.data[7], strlen(data.data[7]));
            strncpy(scan_list->ticket_type2_num, data.data[8], strlen(data.data[8]));
            strncpy(scan_list->ticket_type3_num, data.data[9], strlen(data.data[9]));
            strncpy(scan_list->ticket_type4_num, data.data[10], strlen(data.data[10]));
            strncpy(scan_list->type1_price, data.data[11], strlen(data.data[11]));
            strncpy(scan_list->type2_price, data.data[12], strlen(data.data[12]));
            strncpy(scan_list->type3_price, data.data[13], strlen(data.data[13]));
            strncpy(scan_list->type4_price, data.data[14], strlen(data.data[14]));
            ack_data = ADMIN_CHANGE_TICKET_SUCCESS_ACK;
	    break;
        } else {
            ack_data = ADMIN_CHANGE_TICKET_FALSE_ACK;
        }
    }

    list_for_each (pos2, user_ticket_head) {
        if (0 == strcmp(scan_list->train_number, old_train_number)) {
            strncpy(scan_list->train_number, data.data[1], strlen(data.data[1]));
            strncpy(scan_list->origin_place, data.data[2], strlen(data.data[2]));
            strncpy(scan_list->destination, data.data[3], strlen(data.data[3]));
            strncpy(scan_list->departure_time, data.data[4], strlen(data.data[4]));
            strncpy(scan_list->arrival_time, data.data[5], strlen(data.data[5]));
            strncpy(scan_list->date, data.data[6], strlen(data.data[6]));
        }
    }
    send_ack(clientfd, ack_data);
}

/**
 * @brief:修改用户信息
 */
void change_user(struct data_packet data, int clientfd, struct list_head *user_head)
{
    char old_user_id[USER_ID_SIZE];
    struct list_head *pos;
    struct user *scan_list;
    char ack_data;
    int i;

    strncpy(old_user_id, data.data[0], strlen(data.data[0]));
    old_user_id[strlen(data.data[0])] = '\0';
    list_for_each (pos, user_head) {
        scan_list = list_entry(pos, struct user, list);
        if (0 == strcmp(scan_list->user_id, old_user_id)) {
            /* 清空数据 */
            for (i = 0; i < sizeof(scan_list->user_id); i++) {
                scan_list->user_id[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->passwd); i++) {
                scan_list->passwd[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->name); i++) {
                scan_list->name[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->citizen_id); i++) {
                scan_list->citizen_id[i] = 0;
            }
            for (i = 0; i < sizeof(scan_list->phone_num); i++) {
                scan_list->phone_num[i] = 0;
            }
            /* 导入数据 */
            strncpy(scan_list->user_id, data.data[1], strlen(data.data[1]));
            strncpy(scan_list->passwd, data.data[2], strlen(data.data[2]));
            strncpy(scan_list->name, data.data[3], strlen(data.data[3]));
            strncpy(scan_list->citizen_id, data.data[4], strlen(data.data[4]));
            strncpy(scan_list->phone_num, data.data[5], strlen(data.data[5]));

            ack_data = ADMIN_CHANGE_USER_SUCCESS_ACK;
            break;
        } else {
            ack_data = ADMIN_CHANGE_USER_FALSE_ACK;
        }
    }

    send_ack(clientfd, ack_data);
}

/**
 * @brief:用户查询本地车票
 */
int user_find_ticket(struct data_packet data, int clientfd, struct list_head *ticket_head, char *ticket_buffer)
{
    struct list_head *pos;
    struct ticket *scan_list;
    int ret = false;

    list_for_each (pos, ticket_head) {
        scan_list = list_entry(pos, struct ticket, list);
        if (0 == compare_ticket(scan_list->origin_place, data.data[0]) &&
        0 == compare_ticket(scan_list->destination, data.data[1]) &&
        0 == strcmp(scan_list->date, data.data[2])) {
            strcat(ticket_buffer, scan_list->origin_place);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, scan_list->destination);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, scan_list->departure_time);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, scan_list->arrival_time);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, scan_list->train_number);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, scan_list->type1_price);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, scan_list->type2_price);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, scan_list->type3_price);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, scan_list->type4_price);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, scan_list->date);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, scan_list->ticket_type1_num);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, scan_list->ticket_type2_num);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, scan_list->ticket_type3_num);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, scan_list->ticket_type4_num);
            strcat(ticket_buffer, "|");
            strcat(ticket_buffer, ",");
            ret = true;
        }
    }
    strcat(ticket_buffer, ".");
    return ret;
}

/**
 * @brief:将int转换成char
 */
static void itoa(int i, char* string)
{
    int power,j;
    j=i;
    for(power=1;j>=10;j/=10)
        power*=10;
    for(;power>0;power/=10)
    {
        *string++='0'+i/power;
        i%=power;
    }
    *string='\0';
}
